iT邦幫忙

2021 iThome 鐵人賽

DAY 9
1
DevOps

k8s 入門學習 30天系列 第 9

IT 鐵人賽 k8s 入門30天 -- day9 Organizing your components with K8s Namespaces

  • 分享至 

  • xImage
  •  

前言

今天將會介紹 k8s Namespace

針對 Namespace 的作用, 還有何時該使用 Namespace 跟用法做說明

什麼是 Namespace?

在 k8s 叢集可以允許一個實體叢集具有多個虛擬叢集

而這些虛擬叢集就是所謂的 Namespace

在 k8s 叢集使用 Namespace 來針對叢集資源做管理

基礎的 k8s 叢集系統會有預設的以下4個 Namespace

kube-system

內部有一些 k8s 在使用系統程序

比如說 Kublet 還有 Control Plane 等等

kube-public

內部存放一些可以被公開存取的資源

比如說 ConfigMap

kube-node-lease

用來存放一些結點相關的物件

可以用來偵測結點狀態, 讓 kubelet 對結點送 heartbeats 檢測

default

預設存放使用者建立的資源

使用要者要使用自定義的 Namespace

可以使用以下指令

kubectl create namespace $namespace_name

舉例來說: 建立名稱為 my-namespace 的 Namespace

kubectl create namespace my-namespace

或者使用設定檔 my-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

再使用下面指令建立:

kubectl create -f my-namespace

為何要使用 Namespace?

資源分類

想像假設把所有資源都直接放在 default namespace

當系統變複雜, 所有資源都會散佈在一起, 不好分類檢視

所以比較好的方式是把每個資源根據用途做分類

並且切割出分類項目的 Namespaces, 再依據不同分類放置對應的 Namespace

避免佈署衝突: 多個團隊使用同一個 k8s cluster

多個團隊使用同一個 k8s cluster, 有可能在佈署資源時遇到佈署名稱衝突的問題

舉例來說: 恰巧兩個 team 都發佈一個叫作 logger-app 的 deployment

這時, 如果沒有用 Namespace 切分就會遇到同名稱的 deployment 相互干擾的問題

這時就可以用 Namespace 做資源隔離給每個 team 給不同 Namespace , 這樣就不用擔心會被其他 team 影響

資源分享: 在不同的環境透過 Namespace 共享相同 Service

如果根據佈署環境切分成 staging 與 production 兩個 Namespace

另外把 nginx, elastic 相關的分別放置在 Nginx-Ingress-Controller, Elastic-Stack 兩個 Namespace

這時兩個佈署環境就可以透過 Namespace 共享這些 Service

資源分享案例: 藍綠佈署

藍綠佈署是指同一個應用或是服務根據設定同時佈署兩種版本來做測試

而再兩種佈署裡, 底層用到的資源是相同的比如 Nginx-Ingress-Controller, Elastic-Stack

透過 Namespace 限制存取或是資源

假設有2個團隊 team A, team B

可以利用 Namespace 限制

team A 只能在 Namespace team_A_space 發佈服務, 建立資源

team B 只能再 Namespace team_B_space 發佈服務, 建立資源

彼此不干預各自團隊的開發佈署

另外也可以限制每個 Namespace 最多擁有多少資源比如CPU, RAM 等等

如此可以避免某一個 team 過度占用共有資源

Namespace 的特性

大多數的資源無法跨 Namespace 來存取

舉例來說:

假設有一個 Namespace Project_A 內部有一個 ConfigMap 設定關於存取 Namespace database 的 database_url

在另一個 Namespace Project_B 內部的服務就無法透過 Namespace Project_A 內部的 ConfigMap 來存取 Namespace database

必須要在 Namespace Project_B 內部建立一個 ConfigMap 設定關於存取 Namespace database 的 database_url

這樣 Namespace Project_B 的服務才能透過內部的 ConfigMap 拿到存取 Namespace database 的 database_url 來存取 DB

所以每個 Namespace 必須有自己的 ConfigMap, Secrets

注意的是 Service 可以跨 Namespace 來存取

而體現在設定檔就如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
data:
  db_url: mysql-service.database

注意的是 上面 ConfigMap 的 db_url 組成是以下模式組成

${service_name}.${namespace_name}

有些元件無法在 Namespace 建立

這些元件在 k8s 叢集裡是全域的

無法用 Namespace 來隔離

比如: Volume, Node

可以透過以下指令列出無法使用 Namespace 隔離的所有元件

kubectl api-resources --namespaced=false

相對的, 也可以用以下指令列出所有可用 Namespace 隔離的元件

kubectl api-resources --namespaced=true

建立在 Namespace 的元件

首先建立一個設定檔 mysql-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
data:
  db_url: mysql-service.database

假設直接操作以下指令

kubectl apply -f mysql-configmap.yaml

會發現因為沒指定 Namespace 最後會直接放到 Default Namespace

而如果要把這個 ConfigMap 放到 my-namespace 下

有兩個方式

1 kubectl 指令

kubectl apply -f mysql-configmap.yaml --namespace=my-namespace

2 設定檔的方式
更新 mysql-configmap.yaml 如下

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
  namespace: my-namespace
data:
  db_url: mysql-service.database

在 metadata的部份指定 namespace

查詢已存在的 ConfigMap

更換使用中的 Namespace

假設今天在不同團隊使用不同 Namespace 變成要一直指定 -n 在 kubectl 指令會很麻煩

所以比較好的方式是用一個 command 去修改目前操作的 Namespace

然而原生的 kubectl 沒有這項功能

所以只能透過一個外掛工具 kubectx/kubens 來處理

安裝 kubectx

ref: https://snoopy30485.github.io/2020/10/06/%E4%BD%BF%E7%94%A8kubectx-kubens%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2context%E5%92%8Cnamespace/

git clone https://github.com/ahmetb/kubectx

sudo cp kubectx/kube* /usr/local/bin/

當安裝成功後

就可以執行以下指令列出所有的 namespace

上面顯示黃色的就是預設的 namespace

然後透過以下指令切換 namespace

kubens $namespace_name

切換到 my-namespace 就是以下指令

切換之後結果

其他

刪除 Namespace 指令

kubectl delete namespaces $namespace_name

要注意的是, 當刪除 namespace, 代表 namespace 下的所有佈署都會被刪除

後記

使用 Namespace 能夠有效地分類資源

雖然官方建議當叢集少於10人的時候就不需要使用 Namespace

可是透過 Namespace 將資源分類其實對於資源管理來說其實還是優於散佈所有資源在 default Namespace


上一篇
IT 鐵人賽 k8s 入門30天 -- day8 Demo Project: MongoDB and MongoExpress
下一篇
IT 鐵人賽 k8s 入門30天 -- day10 K8s Ingress explained
系列文
k8s 入門學習 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
jackeir
iT邦新手 5 級 ‧ 2022-05-26 10:17:40

請問一下mongodb-configmap.yaml裡面, 其實在database_url還是指向到mongodb-service, 這部份可以直接在mongo-express-deployment.yaml就指定mongodb-service而不額外寫configmap嗎?

json_liang iT邦研究生 4 級 ‧ 2022-05-27 12:07:00 檢舉

在回答你的問題之前,我想先說明 ConfigMap 的用途。
使用 ConfigMap 最主要用意,是讓在同一個 cluster 內的 deployment 都可以透過 ConfigMap 去存取這樣的 Config。分離掉 deployment 與一些 service url 的相依性。

然後回到你的問題,你是想問
mongo-express-deployment.yaml 所用到的 database_url
是否可以直接在文件內指定而不使用 ConfigMap 設定。

以我在上一篇的設定是可以的。
因為已經使用 Service 來把 mongodb 對應到 Service。
不會讓mongo-express-deployment 被 mongodb-deployment 綁定。

但是 考慮到一個情境,假設今天想要把 mongo-express 對應到的 mongodb-service 做抽換這個時候,就必須要把 mongo-express重新整個做 deployment 更換。

如果使用 ConfigMap ,會做更換的就只有 ConfigMap的設定。 在deployment 讀取到 ConfigMap 變更後,會自動修改讀取的 database_url ,而不需要做整個重建 deployment。

我個人覺得這是為何需要額外做 ConfigMap 的主要原因。

我要留言

立即登入留言